using Cysharp.Threading.Tasks;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Networking;

namespace Test
{
    public class TestNetworkFrame : MonoBehaviour
    {
        private const string URL = "http://localhost:3000";

        private async void Start()
        {
            string response = await GetRequestAsync(URL);
            Debug.Log("Server Response: " + response);
        }

        private async void Update()
        {
            if (Keyboard.current.digit1Key.wasPressedThisFrame)
            {
                var result = await PostDataAsync<float>("test/postData", new { time = Time.time });
                if (result.success)
                {
                    Debug.Log(result.data);
                }
            }
            if (Keyboard.current.digit2Key.wasPressedThisFrame)
            {
                var result = await PostDataAsync<List<Protos.TestUniversalConfig>>("test/loadConfig", null);
                if (result.success)
                {
                    foreach (var config in result.data)
                    {
                        Debug.Log($"{config.id}: {config.desc}");
                    }
                }
            }
        }

        public async UniTask<string> GetRequestAsync(string url)
        {
            try
            {
                using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
                {
                    await webRequest.SendWebRequest();

                    if (webRequest.result == UnityWebRequest.Result.ConnectionError ||
                        webRequest.result == UnityWebRequest.Result.ProtocolError)
                    {
                        Debug.LogError("Error: " + webRequest.error);
                        return null;
                    }
                    else
                    {
                        return webRequest.downloadHandler.text;
                    }
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public async UniTask<SimpleResponse<T>> PostDataAsync<T>(string path, object data)
        {
            try
            {
                var fullPath = $"{URL}/{path}";
                var json = data.ToJson();
                Debug.Log($"Post: {fullPath}, {json}");
                using (var request = new UnityWebRequest(fullPath, "POST"))
                {
                    byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(json);
                    request.uploadHandler = new UploadHandlerRaw(bodyRaw);
                    request.downloadHandler = new DownloadHandlerBuffer();
                    request.SetRequestHeader("Content-Type", "application/json");

                    await request.SendWebRequest();

                    if (request.result != UnityWebRequest.Result.Success)
                    {
                        Debug.LogError($"Error: {request.error}");
                        return null;
                    }

                    return request.downloadHandler.text.ToObject<SimpleResponse<T>>();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public class SimpleResponse<T>
        {
            public int code;
            public string message;
            public T data;

            public bool success => code == 1;
        }
    }
}